package com.sgs.carbon.web.modules.common.controller.auth;

import com.sgs.carbon.common.enums.CommonStatusEnum;
import com.sgs.carbon.common.pojo.CommonResult;
import com.sgs.carbon.common.util.collection.SetUtils;
import com.sgs.carbon.common.util.servlet.ServletUtils;
import com.sgs.carbon.starter.operatelog.core.annotations.OperateLog;
import com.sgs.carbon.starter.security.core.util.SecurityUtils;
import com.sgs.carbon.starter.web.core.controller.BaseController;
import com.sgs.carbon.web.modules.common.controller.auth.vo.base.SysAuthLoginReqVO;
import com.sgs.carbon.web.modules.common.controller.auth.vo.base.SysAuthLoginRespVO;
import com.sgs.carbon.web.modules.common.controller.auth.vo.base.SysAuthMenuRespVO;
import com.sgs.carbon.web.modules.common.controller.auth.vo.base.SysAuthPermissionInfoRespVO;
import com.sgs.carbon.web.modules.common.convert.auth.SysAuthConvert;
import com.sgs.carbon.web.modules.common.dal.dataobject.permission.SysMenuDO;
import com.sgs.carbon.web.modules.common.dal.dataobject.permission.SysRoleDO;
import com.sgs.carbon.web.modules.common.dal.dataobject.user.SysUserDO;
import com.sgs.carbon.web.modules.common.enums.permission.MenuTypeEnum;
import com.sgs.carbon.web.modules.common.service.auth.SysAuthService;
import com.sgs.carbon.web.modules.common.service.permission.SysPermissionService;
import com.sgs.carbon.web.modules.common.service.permission.SysRoleService;
import com.sgs.carbon.web.modules.common.service.user.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

/**
 * 认证管理 Controller
 *
 * @author Dave Liu
 * @date 2021-10-09
 */
@Validated
@Api(tags = "认证管理")
@RestController
@RequestMapping("/")
public class SysAuthController extends BaseController {

    @Autowired
    private SysAuthService authService;

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysRoleService roleService;

    @Autowired
    private SysPermissionService permissionService;


    @PostMapping("/login")
    @ApiOperation("使用账号密码登录")
    @OperateLog(enable = false)
    public CommonResult<SysAuthLoginRespVO> login(@RequestBody @Valid SysAuthLoginReqVO reqVO) {
        String token = authService.login(reqVO, ServletUtils.getClientIP(), ServletUtils.getUserAgent());
        // 返回结果
        return success(SysAuthLoginRespVO.builder().token(token).build());
    }

    @GetMapping("/get-permission-info")
    @ApiOperation("获取登陆用户的权限信息")
    public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() {
        // 获得用户信息
        SysUserDO user = userService.getUser(SecurityUtils.getLoginUserId());
        if (user == null) {
            return null;
        }
        // 获得角色列表
        List<SysRoleDO> roleList = roleService.getRolesFromCache(SecurityUtils.getLoginUserRoleIds());
        // 获得菜单列表
        List<SysMenuDO> menuList = permissionService.getRoleMenusFromCache(
                // 注意: 基于登陆的角色, 因为后续的权限判断也是基于它
                SecurityUtils.getLoginUserRoleIds(),
                SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()),
                SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus()));
        // 拼接结果返回
        return success(SysAuthConvert.INSTANCE.convert(user, roleList, menuList));
    }

    @GetMapping("list-menus")
    @ApiOperation("获得登陆用户的菜单列表")
    public CommonResult<List<SysAuthMenuRespVO>> getMenus() {
        // 获得用户拥有的菜单列表
        List<SysMenuDO> menuList = permissionService.getRoleMenusFromCache(
                // 注意: 基于登陆的角色, 因为后续的权限判断也是基于它
                SecurityUtils.getLoginUserRoleIds(),
                // 只要目录和菜单类型
                SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()),
                // 只要开启的
                SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus()));
        // 转换成 Tree 结构返回
        return success(SysAuthConvert.INSTANCE.buildMenuTree(menuList));
    }

}
